#pragma once

// ansi string
class DString 
{
public:

    DString( u32_t num = 0);
    DString( const char* c_str);
    DString( const DString& other);
	~DString();

	// num buf size
	s32_t	Num() const;
	void	Clear();

    // return pointer to const string
    operator const char*() const;

	// operator[]
	char const& operator[](s32_t index);

	void			FormatSelf(const char* str, ...);
	static DString	Format( const char* str, ...);

    s32_t Cmp(const char* rhs) const;
    s32_t ICmp(const char* rhs) const;

    DString Sub( s32_t begin, s32_t end) const;

    DString Split( const char* delimeters, s32_t& begin) const;
    
    s32_t Find(const char* str, s32_t start = 0) const;
    s32_t FindFristOf(const char* str, s32_t start = 0) const;

	void Replace(const char* toReplace , const char* replaceWith);

    void Upper();
    void Lower();

	void Cat( const char* pcStr);
	void Cat( char ch);

	DString& operator=(DString& stringSrc);
	DString& operator=(const char* lpsz);
	DString& operator=(char ch);
	DString& operator=(char* lpsz);
	DString& operator+=(char ch);
	DString& operator+=(DString& stringSrc);
	DString& operator+=(char* lpsz);
	DString& operator+=(const char* pcString);

protected:

	void _makeInstanceData( bool forceCopy);
	void _makeInstanceDataAddMakeRoom( s32_t num, bool forceCopy);
    bool	_makeRoom( s32_t num);
	struct StrData* mData;

};

typedef DString ds_t;

inline bool  operator==(const DString& s1, const DString& s2)
{ 
    return s1.Cmp(s2) == 0; 
}

inline bool  operator==(const DString& s1, const char* s2)
{ 
    return s1.Cmp(s2) == 0; 
}

inline bool  operator==(const char* s1, const DString& s2)
{ 
    return s2.Cmp(s1) == 0; 
}

inline bool  operator!=(const DString& s1, const DString& s2)
{ 
    return s1.Cmp(s2) != 0; 
}

inline bool  operator!=(const DString& s1, const char* s2)
{ 
    return s1.Cmp(s2) != 0; 
}

inline bool  operator!=(const char* s1, const DString& s2)
{ 
    return s2.Cmp(s1) != 0; 
}


DString  operator+(const DString& string1, const DString& string2);
DString  operator+(const DString& string1, char* pcStr);
DString  operator+(char* pcStr, const DString& string1);
DString  operator+(const DString& string, char ch);
DString  operator+(char ch, const DString& string);